<?php

namespace app\api\controller;

use app\api\model\Activity as ActivityModel;
use app\api\model\Setting as SettingModel;
use app\store\model\Activity as storeActivityModel;
use app\api\model\ActivitySign;
use Grafika\Color;
use Grafika\Grafika;
use app\common\service\qrcode\Base;
use app\common\service\qrcode;
use think\Db;
use think\Log;

/**
 * 活动控制器
 * Class Activity
 * @package app\api\controller
 */
class Activity extends Controller
{
    /**
     * 活动列表
     * @param int $team_id
     * @param int $user_id 个人中心活动列表控制权限用
     * @param int $isfront 0||1 1为首页用，区分活动列表审核状态，首页只看审核通过的
     * @return array
     * @throws \think\exception\DbException
     */
    public function lists($team_id = 0, $user_id = 0, $isfront = 0)
    {
        $user = $this->getUser();
        $shanghui_id = $user["shanghui_id"];//当前用户的商会id
        $model = new ActivityModel;
        if ($isfront != 1) {
            if ($user['grade_id'] == 10008) {//此条为所谓秘书长即总管理发布活动
                $team_id = 0;//为代表处活动
            }
            if ($user['grade_id'] == 10009) {//此条为所谓秘书长即总管理发布活动
                $user_id = 1;//为代表处活动
            }
        }
        $list = $model->getList($team_id, $user_id, 5, $isfront, $shanghui_id);
        $userId = $user['user_id'];
        //查找报名表
        $signup = (new ActivitySign)->where("user_id", "=", $userId)->select()->toArray();
        $signup = array_column($signup, "activity_id");
        foreach ($list as &$items) {
            $items["sign"] = in_array($items["activity_id"], $signup) ? 1 : 0; //判断是否报名
        }
        return $this->renderSuccess(compact('list'));
    }

    /**
     * 待审核活动列表
     * @param int $team_id
     * @return array
     * @throws \think\exception\DbException
     */
    public function examineLists()
    {
        $user = $this->getUser();
        $shanghui_id = $user["shanghui_id"];//当前用户的商会id
        $model = new ActivityModel;
        $list = $model->getExamineList(5,$shanghui_id);
        return $this->renderSuccess(compact('list'));
    }

    /**
     * 审核活动
     * @param int $team_id
     * @return array
     * @throws \think\exception\DbException
     */
    public function examine()
    {
        $user = $this->getUser();
        $shanghui_id = $user["shanghui_id"];//当前用户的商会id
        $param = input('param.');
        $res = Db::name('activity')
            ->where('activity_id', $param['activity_id'])
            ->where('shanghui_id', $shanghui_id)
            ->update([
                'examine_status' => $param['status'],
                'examine_remark' => $param['remark'],
                'examine_time' => date('Y-m-d H:i:s'),
                'examine_uid' => $user['user_id']
            ]);
        if (!$res) {
            return $this->renderError('审核失败，请重试~');
        }
        return $this->renderSuccess([], '审核成功');
    }

    /**
     * 活动详情
     * @param $activity_id
     * @return array
     * @throws \app\common\exception\BaseException
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
    public function detail($activity_id)
    {
        $user = $this->getUser();
        $signup = (new ActivitySign)->where("user_id", "=", $user['user_id'])->select()->toArray();
        $signup = array_column($signup, "activity_id");
        $detail = ActivityModel::detail($activity_id);
        $detail["sign"] = in_array($detail["activity_id"], $signup) ? 1 : 0; //判断是否报名
        $sign_num = Db::name('activity_sign')->where('activity_id', $activity_id)->count();
        $detail['registered'] = $sign_num;//已报名人数
        return $this->renderSuccess(compact('detail'));
    }

    // 活动标签
    public function theme()
    {
        $data = [
            ["value" => '会议', "name" => '会议'],
            ["value" => '活动', "name" => '活动'],
            ["value" => '培训', "name" => '培训'],
            ["value" => '其他', "name" => '其他'],
        ];
        return $this->renderSuccess(compact('data'));
    }

    /**
     * 添加/编辑活动
     */
    public function release()
    {
        $param = input('param.');
        $user = $this->getUser();
        $param['shanghui_id'] = $user["shanghui_id"];//当前用户的商会id
        $param['team_id'] = $user['team_id'];
        if ($user['grade_id'] == 10008) {//此条为所谓秘书长即总管理发布活动
            $param['team_id'] = 0;//为代表处活动
        }
        if ($user['grade_id'] == 10009 && $param['location'] == 1) {//此条为所谓秘书长即总管理发布活动
            $param['team_id'] = 0;//为代表处活动
        }
        if (!$param['activity_id']) {
            $param['user_id'] = $user['user_id'];
            // 新增记录
            $model = new ActivityModel;
            $res = $model->add($param);
            if ($res) {
                return $this->renderSuccess('发布成功');
            }
            return $this->renderError($model->getError() ?: '发布失败');
        }
        $param['update_user'] = $user['user_id'];
        $model = ActivityModel::detail($param['activity_id']);
        $res = $model->edit($param);
        if ($res) {
            return $this->renderSuccess('更新成功');
        }
        return $this->renderError($model->getError() ?: '更新失败');
    }

    /**
     * 添加/活动报名
     */
    public function signup()
    {
        $param = input('param.');
        $user = $this->getUser();
        $param['user_id'] = $user['user_id'];
        $res = (new ActivitySign)->allowField(true)->save($param);
        if ($res) {
            return $this->renderSuccess('报名成功');
        }
        return $this->renderError((new ActivitySign)->getError() ?: '报名失败');
    }

    /**
     * 扫码弹出签到信息
     */
    public function signInfo()
    {
        $param = input('param.');
        if (!isset($param['activity_id'])) {
            return $this->renderJson(2, '活动id参数有误', [["backUrl" => "/pages/index/index"]]);

        }
        $user = $this->getUser();
        $data = Db::name('activity_sign')->where('user_id', $user['user_id'])->where('activity_id', $param['activity_id'])->find();
        if (!$data) {
            Log::record("activity_id=" . $param['activity_id'] . "user_id=" . $user['user_id']);
            return $this->renderJson(2, '您没有报名，或是报名已失效', ["backUrl" => "/pages/index/index"]);
        }
        if ($data['sign_status'] == 1) {
            return $this->renderJson(2, '您已经签到成功', ["backUrl" => "/pages/index/index"]);
        }
        return $this->renderSuccess($data, 'success');
    }

    /**
     * @return mixed
     * @throws \app\common\exception\BaseException
     * @throws \think\exception\DbException
     * @throws \Exception
     */
    public function getImage($activity_id)
    {
        // 小程序id
        $wxappId = $this->wxapp_id;
        // 商品海报背景图
        // $backdrop = __DIR__ . '/../resource/goods_bg.png';
        // 下载商品首图
        // $goodsUrl = (new Base())->saveTempImage($wxappId, 10509, 'activity');
        // 小程序码参数
        $scene = "activity_id:" . $activity_id;
        // 下载小程序码
        $qrcode = (new Base())->saveQrcode($wxappId, $scene, 'pages/sign/index');
        // 拼接海报图
        return $this->renderSuccess($this->savePoster($qrcode, $activity_id));
    }

    /**
     * 拼接海报图
     * @param $backdrop
     * @param $goodsUrl
     * @param $qrcode
     * @return string
     * @throws \Exception
     */
    private function savePoster($qrcode, $activity_id)
    {
        // 实例化图像编辑器
        $editor = Grafika::createEditor(['Gd']);
        // 打开小程序码
        $editor->open($qrcodeImage, $qrcode);
        // 重设小程序码宽高
        $editor->resizeExact($qrcodeImage, 500, 500);
        // 保存图片
        $editor->save($qrcodeImage, $this->getPosterPath($activity_id));
        return $this->getPosterUrl($activity_id);
    }

    /**
     * 处理文字超出长度自动换行
     * @param integer $fontsize 字体大小
     * @param integer $angle 角度
     * @param string $fontface 字体名称
     * @param string $string 字符串
     * @param integer $width 预设宽度
     * @param null $max_line 最多行数
     * @return string
     */
    private function wrapText($fontsize, $angle, $fontface, $string, $width, $max_line = null)
    {
        // 这几个变量分别是 字体大小, 角度, 字体名称, 字符串, 预设宽度
        $content = "";
        // 将字符串拆分成一个个单字 保存到数组 letter 中
        $letter = [];
        for ($i = 0; $i < mb_strlen($string, 'UTF-8'); $i++) {
            $letter[] = mb_substr($string, $i, 1, 'UTF-8');
        }
        $line_count = 0;
        foreach ($letter as $l) {
            $testbox = imagettfbbox($fontsize, $angle, $fontface, $content . ' ' . $l);
            // 判断拼接后的字符串是否超过预设的宽度
            if (($testbox[2] > $width) && ($content !== "")) {
                $line_count++;
                if ($max_line && $line_count >= $max_line) {
                    $content = mb_substr($content, 0, -1, 'UTF-8') . "...";
                    break;
                }
                $content .= "\n";
            }
            $content .= $l;
        }
        return $content;
    }

    /**
     * 海报图文件路径
     * @return string
     */
    private function getPosterPath($activity_id)
    {
        // 保存路径
        $tempPath = WEB_PATH . 'temp' . '/' . $this->wxapp_id . '/';
        !is_dir($tempPath) && mkdir($tempPath, 0755, true);
        return $tempPath . 'lion_activity_' . $activity_id . '.png';
    }


    /**
     * 海报图url
     * @return string
     */
    private function getPosterUrl($activity_id)
    {
        return \base_url() . 'temp/' . $this->wxapp_id . '/' . 'lion_activity_' . $activity_id . '.png' . '?t=' . time();
    }

    /**
     * 活动签到
     * @return string
     */
    public function signIn()
    {
        //fix积分设置签到给积分，给人加完别忘了累积到分队积分
        $param = input('param.');
        if (!isset($param['activity_id'])) {
            return $this->renderError('参数有误');
        }
        $user = $this->getUser();
        $shanghui_id = $user["shanghui_id"];//当前用户的商会id
        $team_id     = $user["team_id"];    //当前用户的服务队id
        $user_activity = Db::name('activity_sign')
            ->where('activity_id', $param['activity_id'])
            ->where('user_id', $user['user_id'])
            ->find();
        if (!$user_activity) {
            return $this->renderError('未找到您的报名记录');
        }
//        if ($user_activity['pay_status'] != 1) {
//            return $this->renderError('该报名尚未付款，请先付款方可参加活动');
//        }
        if ($user_activity['sign_status'] == 1) {
            return $this->renderError('已经签到成功，无需重复签到');
        }
        $activity = Db::name('activity')->find($param['activity_id']);
        if (!$activity) {
            return $this->renderError('未找到相关活动');
        }
        $setting = Db::name('setting')->where('key', 'sign')->where('wxapp_id', $param['wxapp_id'])->value('values');
        $setting = json_decode($setting, true);
        $distance = $this->getDistance($param['longitude'], $param['latitude'], $activity['longitude'], $activity['latitude'], 1);
        if ($distance > $setting['range']) {
            Log::record('用户经纬度' . $param['longitude'] . ';' . $param['latitude'] . '相差了：' . $distance . '米,活动经纬度' . $activity['longitude'] . ',' . $activity['latitude']);
            return $this->renderError('请在活动' . $setting['range'] . '米范围内签到');
        }
        // 启动事务
        Db::startTrans();
        try {
            Db::name('activity_sign')
                ->where('activity_id', $param['activity_id'])
                ->where('user_id', $user['user_id'])
                ->update([
                    'sign_status' => 1,
                    'real_num' => $param['people_num'],
                    'sign_time' => date('Y-M-d H:i:s', time())]);
            Db::name('shanghui_user')->where('user_id', $user['user_id'])->where('shanghui_id',$shanghui_id)->setInc('points', $setting['points']);
            Db::name('shanghui_user')->where('user_id', $user['user_id'])->where('shanghui_id',$shanghui_id)->setInc('activity_count', 1);
            // 如果有服务队给服务队加积分
            if($team_id){
                Db::name('team')->where('team_id', $team_id)->where('shanghui_id', $shanghui_id)->setInc('points', $setting['points']);     
            }
            
            // 提交事务
            Db::commit();
            return $this->renderSuccess([], '签到成功');
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return $this->renderError('签到失败，' . $e->getMessage());
        }
    }

    /**
     * 计算两点地理坐标之间的距离
     * @param Decimal $longitude1 起点经度
     * @param Decimal $latitude1 起点纬度
     * @param Decimal $longitude2 终点经度
     * @param Decimal $latitude2 终点纬度
     * @param Int $unit 单位 1:米 2:公里
     * @param Int $decimal 精度 保留小数位数
     * @return Decimal
     */
    function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit = 2, $decimal = 2)
    {

        $EARTH_RADIUS = 6370.996; // 地球半径系数
        $PI = 3.1415926;

        $radLat1 = $latitude1 * $PI / 180.0;
        $radLat2 = $latitude2 * $PI / 180.0;

        $radLng1 = $longitude1 * $PI / 180.0;
        $radLng2 = $longitude2 * $PI / 180.0;

        $a = $radLat1 - $radLat2;
        $b = $radLng1 - $radLng2;

        $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
        $distance = $distance * $EARTH_RADIUS * 1000;

        if ($unit == 2) {
            $distance = $distance / 1000;
        }

        return round($distance, $decimal);

    }

    //测试用接口
    public function test()
    {
        $param = input('param.');
        $setting = Db::name('setting')->where('key', 'sign')->where('wxapp_id', $param['wxapp_id'])->value('values');
        $setting = json_decode($setting, true);
        //var_dump($setting['points']);die();
        $distance = $this->getDistance($param['longitude'], $param['latitude'], 121.505114, 38.881886, 1);
        if ($distance > $setting['range']) {
            return $this->renderError('请在活动' . $setting['range'] . '米范围内签到');
        }
        return $this->renderSuccess([], 'success');
    }
}
